/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtCore/QDateTime>
#include <QtMqtt/QMqttClient>
#include <QtWidgets/QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_client = new QMqttClient(this);
    m_client->setHostname(ui->lineEditHost->text());
    m_client->setPort(ui->spinBoxPort->value());

    connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange);
    connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected);

    connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) {
        const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(" Received Topic: ")
                    + topic.name()
                    + QLatin1String(" Message: ")
                    + message
                    + QLatin1Char('\n');
        ui->editLog->insertPlainText(content);
    });

    connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() {
        const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(" PingResponse")
                    + QLatin1Char('\n');
        ui->editLog->insertPlainText(content);
    });
/////////////////////////
    connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname);
    connect(ui->spinBoxPort, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort);

    connect(ui->pushButton_BUZZ, &QPushButton::clicked, this, &MainWindow::handleButtonClick);
    connect(ui->pushButton_fan, &QPushButton::clicked, this, &MainWindow::handleButtonClick);
    connect(ui->pushButton_hum, &QPushButton::clicked, this, &MainWindow::handleButtonClick);
    connect(ui->pushButton_led, &QPushButton::clicked, this, &MainWindow::handleButtonClick);
    connect(ui->pushButton_was, &QPushButton::clicked, this, &MainWindow::handleButtonClick);

    connect(m_client,&QMqttClient::messageReceived, this,&MainWindow::recv);
    ui->checkBox_hum_s->setEnabled(false);
    ui->checkBox_wsa->setEnabled(false);
    ui->checkBox_buzz->setEnabled(false);
    ui->checkBox_FIN->setEnabled(false);
    ui->checkBox_led->setEnabled(false);
///////////
    updateLogStateChange();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_buttonConnect_clicked()
{
    if (m_client->state() == QMqttClient::Disconnected) {
        ui->lineEditHost->setEnabled(false);
        ui->spinBoxPort->setEnabled(false);
        ui->buttonConnect->setText(tr("断开"));
        m_client->connectToHost();
    } else {
        ui->lineEditHost->setEnabled(true);
        ui->spinBoxPort->setEnabled(true);
        ui->buttonConnect->setText(tr("连接"));
        m_client->disconnectFromHost();
    }
}

void MainWindow::on_buttonQuit_clicked()
{
    QApplication::quit();
}

void MainWindow::updateLogStateChange()
{
    const QString content = QDateTime::currentDateTime().toString()
                    + QLatin1String(": State Change")
                    + QString::number(m_client->state())
                    + QLatin1Char('\n');
    ui->editLog->insertPlainText(content);
}

void MainWindow::brokerDisconnected()
{
    ui->lineEditHost->setEnabled(true);
    ui->spinBoxPort->setEnabled(true);
    ui->buttonConnect->setText(tr("连接"));
}

void MainWindow::setClientPort(int p)
{
    m_client->setPort(p);
}

void MainWindow::on_buttonPublish_clicked()
{
    if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8()) == -1)
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
}

void MainWindow::on_buttonSubscribe_clicked()
{
    auto subscription = m_client->subscribe(ui->lineEditTopic->text());
    if (!subscription) {
        QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not subscribe. Is there a valid connection?"));
        return;
    }
}

void MainWindow::recv(const QByteArray &message, const QMqttTopicName &topic)
{
    QString msg = QString::fromUtf8(message);
    QStringList items = msg.split(QRegExp("\\s+"), Qt::SkipEmptyParts);

    QMap<QString, QString> dataMap;

    // 解析格式为"key value"的项
    for (int i = 0; i < items.size() - 1; i += 2) {
        QString key = items[i].trimmed();
        QString value = items[i + 1].trimmed();

        // 移除可能的冒号或其他符号
        key = key.remove(QRegExp("[\\s:]"));

        dataMap[key] = value;
    }

    // 处理解析后的数据
    qDebug() << "解析结果:";
    for (auto it = dataMap.begin(); it != dataMap.end(); ++it) {
        qDebug() << it.key() << "=" << it.value();
    }

    // 提取特定参数
    hum_status = dataMap.value("h", "0").toInt();
    shower_status = dataMap.value("s", "0").toInt();
    buzzer = dataMap.value("b", "0").toInt();
    fan = dataMap.value("f", "0").toInt();
    led = dataMap.value("l", "0").toInt();
    temperature = dataMap.value("tem", "0").toInt();
     humidity = dataMap.value("hum", "0").toInt();
    // hum_status 0  shower_status 0  buzzer 0  fan 0  led 0
    ui->checkBox_hum_s->setChecked(hum_status);
    ui->checkBox_wsa->setChecked(shower_status);
    ui->checkBox_buzz->setChecked(buzzer);
    ui->checkBox_FIN->setChecked(fan);
    ui->checkBox_led->setChecked(led);
    ui->lcdNumber_tem->display(temperature);
    ui->lcdNumber_hum->display(humidity);


}

void MainWindow::handleButtonClick()
{

    QPushButton *senderButton = qobject_cast<QPushButton*>(sender());
    if(!senderButton)return;
    if(senderButton==ui->pushButton_BUZZ)
    {
        bool _buzzer = !buzzer;
       static QString str("b  ");
        str[2] = _buzzer?'1':'0';
        if (m_client->publish(ui->lineEditTopic->text(), str.toUtf8()) == -1)
            QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
    }
    else if(senderButton==ui->pushButton_fan)
    {
        bool _fan = !fan;
       static QString str("f  ");
        str[2] = _fan?'1':'0';
       if (m_client->publish(ui->lineEditTopic->text(), str.toUtf8()) == -1)
            QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
    }
    else if(senderButton==ui->pushButton_hum)
    {
        bool _hum_status = !hum_status;
       static QString str("h  ");
        str[2] = _hum_status?'1':'0';
        if (m_client->publish(ui->lineEditTopic->text(), str.toUtf8()) == -1)
            QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));    }
    else if(senderButton==ui->pushButton_led)
    {
        bool _led = !led;
       static QString str("l  ");
        str[2] = _led?'1':'0';
        if (m_client->publish(ui->lineEditTopic->text(), str.toUtf8()) == -1)
            QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
    }
    else if(senderButton==ui->pushButton_was)
    {
        bool _shower_status = !shower_status;
       static QString str("s  ");
        str[2] = _shower_status?'1':'0';
        if (m_client->publish(ui->lineEditTopic->text(), str.toUtf8()) == -1)
            QMessageBox::critical(this, QLatin1String("Error"), QLatin1String("Could not publish message"));
    }
    else
    {
        return;
    }

}

















